import java.util.ArrayList;

import javax.media.opengl.GL;

import com.sun.opengl.util.texture.Texture;


// this class is the implementation of level 1 drawing. it define the level's room and light.
public class Level1Builder extends LevelBuilder{
	

	private int room;
	ArrayList<Point3D[]> roomsWall;
	Point3D[] floorAbyss;
	

	// ctor
	public Level1Builder() {
		roomsWall = new ArrayList<Point3D[]>(4) ;
		
	}
	@Override
	public boolean checkDoorEnterance(Point3D eyePosition) {
		
		return (eyePosition.z>(forwardWall-100) && eyePosition.x<800 &&eyePosition.x>500);
	}
	
	
	public void buildMap(GL gl){
		double doors [] ={0,0,0,0,800,500,0,0};
		room=make_room(gl,1800,2000,1800,doors,wallTexture,floorTexture,cellingTexture,500,1000,0);
		
		
		leftWall=1800;
		rightWall=0;
		forwardWall=1800;
		backWall=0;
		celling=2000;
		floor=0;
		
	}
	

 private int make_room(GL gl,double sizeX,double sizeY,double sizeZ,double[] doors,Texture wallTexture,Texture floorTexture,Texture cellingTexture,float startAbyss,float endAbyss,float disp){
	 	Point3D[] roomWall = new Point3D[6];

		int room = gl.glGenLists(1);

		gl.glNewList(room, GL.GL_COMPILE);

        gl.glTexParameteri ( GL.GL_TEXTURE_2D,GL.GL_TEXTURE_WRAP_T, GL.GL_REPEAT );
        gl.glTexParameteri( GL.GL_TEXTURE_2D,GL.GL_TEXTURE_WRAP_S, GL.GL_REPEAT );
//        gl.glTexParameteri( GL.GL_TEXTURE_2D,GL.GL_TEXTURE_WRAP_S, GL.GL_CLAMP );

 		//walls
        wallTexture.bind();
		gl.glBegin(GL.GL_QUAD_STRIP);

		roomWall[0]=(new Point3D(0+disp, 0, 0));
		
		
		gl.glTexCoord2f(0.0f, 0.0f);
		gl.glVertex3d(0, 0, 0);
		gl.glTexCoord2f(0.0f,4.0f);
		gl.glVertex3d(0, sizeY, 0);
		
		
		gl.glTexCoord2f((float)(8/(sizeX/doors[0])), 0.0f);
		gl.glVertex3d(doors[0], 0, 0);
		
		gl.glTexCoord2f((float)(8/(sizeX/doors[0])), 4f);
		gl.glVertex3d(doors[0], sizeY, 0);
		

		
		
		gl.glEnd();
		gl.glBegin(GL.GL_QUAD_STRIP);

		gl.glTexCoord2f(0f, 0.0f);
		gl.glVertex3d(doors[1], 0, 0);
		gl.glTexCoord2f(0f, 4f);
		gl.glVertex3d(doors[1], sizeY, 0);

		roomWall[1]=(new Point3D(sizeX+disp, 0, 0));
		
		gl.glTexCoord2f(8f, 0.0f);
		gl.glVertex3d(sizeX, 0, 0);
		gl.glTexCoord2f(8f, 4f);
		gl.glVertex3d(sizeX, sizeY, 0);

		
		gl.glTexCoord2f(0.0f, 0.0f);
		gl.glVertex3d(sizeX, 0, doors[2]);
		gl.glTexCoord2f(0.0f,4.0f);
		gl.glVertex3d(sizeX, sizeY, doors[2]);
		
		gl.glEnd();
		gl.glBegin(GL.GL_QUAD_STRIP);
		
		gl.glTexCoord2f(0.0f, 0.0f);
		gl.glVertex3d(sizeX, 0, doors[3]);
		gl.glTexCoord2f(0.0f,4.0f);
		gl.glVertex3d(sizeX, sizeY, doors[3]);
		
		roomWall[2]=(new Point3D(sizeX+disp, 0, sizeZ));
		
		gl.glTexCoord2f(8f, 0.0f);
		gl.glVertex3d(sizeX, 0, sizeZ);
		gl.glTexCoord2f(8f,4.0f);
		gl.glVertex3d(sizeX, sizeY, sizeZ);
		
	
		
		gl.glTexCoord2f(0.0f, 0.0f);
		gl.glVertex3d(doors[4], 0, sizeZ);
		gl.glTexCoord2f(0.0f,4.0f);
		gl.glVertex3d(doors[4], sizeY, sizeZ);
		
		gl.glEnd();
		gl.glBegin(GL.GL_QUAD_STRIP);
		
		gl.glTexCoord2f(4.0f, 0.0f);
		gl.glVertex3d(doors[5], 0, sizeZ);
		gl.glTexCoord2f(4.0f,4.0f);
		gl.glVertex3d(doors[5], sizeY, sizeZ);
		
		roomWall[3]=(new Point3D(0+disp, 0, sizeZ));
	
		gl.glTexCoord2f(8f, 0.0f);
		gl.glVertex3d(0, 0, sizeZ);
		gl.glTexCoord2f(8f, 4f);
		gl.glVertex3d(0, sizeY, sizeZ);
///
		gl.glTexCoord2f(0.0f, 0.0f);
		gl.glVertex3d(0, 0, doors[6]);
		gl.glTexCoord2f(0.0f,4.0f);
		gl.glVertex3d(0, sizeY, doors[6]);
		
		gl.glEnd();
		gl.glBegin(GL.GL_QUAD_STRIP);
		
		gl.glTexCoord2f(0.0f, 0.0f);
		gl.glVertex3d(0, 0, doors[7]);
		gl.glTexCoord2f(0.0f,4.0f);
		gl.glVertex3d(0, sizeY, doors[7]);
		

		///
		gl.glTexCoord2f(8f, 0.0f);
		gl.glVertex3d(0, 0, 0);
		gl.glTexCoord2f(8f,4.0f);
		gl.glVertex3d(0, sizeY, 0);
	    gl.glEnd();
	    
	    // build floor
        gl.glTexParameteri ( GL.GL_TEXTURE_2D,GL.GL_TEXTURE_WRAP_T, GL.GL_REPEAT );
        gl.glTexParameteri( GL.GL_TEXTURE_2D,GL.GL_TEXTURE_WRAP_S, GL.GL_REPEAT );
        floorTexture.bind();
        gl.glBegin(GL.GL_QUAD_STRIP);
        

        gl.glTexCoord2f(0.0f, 0.0f);
		gl.glVertex3d(0,0 , 0);
		gl.glTexCoord2f(0.0f,8.0f);
		gl.glVertex3d(sizeX, 0, 0);
		
	
		if (startAbyss!=endAbyss){
			floorAbyss = new Point3D[4];
			gl.glTexCoord2f(4.0f, 0.0f);
			gl.glVertex3d(0, 0, startAbyss);
			gl.glTexCoord2f(4.0f,8.0f);
			gl.glVertex3d(sizeX, 0, startAbyss);
			
			gl.glTexCoord2f(0.0f, 0.0f);
			gl.glVertex3d(0, -1000, startAbyss);
			gl.glTexCoord2f(0.0f,8.0f);
			gl.glVertex3d(sizeX, -1000, startAbyss);
			
			
			//sideways
			gl.glEnd();
			gl.glBegin(GL.GL_QUAD_STRIP);

			gl.glTexCoord2f(4.0f, 0.0f);
			gl.glVertex3d(0, 0, startAbyss);
			gl.glTexCoord2f(4.0f,4.0f);
			gl.glVertex3d(0, 0, endAbyss);
			
			gl.glTexCoord2f(0.0f, 0.0f);
			gl.glVertex3d(0, -1000, startAbyss);
			gl.glTexCoord2f(0.0f,4.0f);
			gl.glVertex3d(0, -1000, endAbyss);
			
			
			gl.glEnd();
			gl.glBegin(GL.GL_QUAD_STRIP);
			
			gl.glTexCoord2f(4.0f, 0.0f);
			gl.glVertex3d(sizeX, 0, startAbyss);
			gl.glTexCoord2f(4.0f,4.0f);
			gl.glVertex3d(sizeX, 0, endAbyss);
			
			gl.glTexCoord2f(0.0f, 0.0f);
			gl.glVertex3d(sizeX, -1000, startAbyss);
			gl.glTexCoord2f(0.0f,4.0f);
			gl.glVertex3d(sizeX, -1000, endAbyss);
			
			
			gl.glEnd();
			gl.glBegin(GL.GL_QUAD_STRIP);
			
			//up and to the end
			gl.glTexCoord2f(0.0f, 0.0f);
			gl.glVertex3d(0, -1000, endAbyss);
			gl.glTexCoord2f(0.0f,8.0f);
			gl.glVertex3d(sizeX, -1000, endAbyss);
			
			
			gl.glTexCoord2f(4.0f, 0.0f);
			gl.glVertex3d(0, 0, endAbyss);
			gl.glTexCoord2f(4.0f,8.0f);
			gl.glVertex3d(sizeX, 0, endAbyss);
			 

			floorAbyss[0] = new Point3D(0, 0, startAbyss);
			floorAbyss[1] = new Point3D(0, 0, endAbyss);
			floorAbyss[2] = new Point3D(sizeX, 0, endAbyss);
			floorAbyss[3] = new Point3D(sizeX, 0, startAbyss);

			
			

		}
		
		gl.glTexCoord2f(0.0f, 0.0f);
		gl.glVertex3d(0, 0, sizeZ);
		gl.glTexCoord2f(0.0f,8f);
		gl.glVertex3d(sizeX, 0, sizeZ);
		gl.glEnd();
       
      
	    gl.glTexParameteri ( GL.GL_TEXTURE_2D,GL.GL_TEXTURE_WRAP_T, GL.GL_REPEAT );
	    gl.glTexParameteri( GL.GL_TEXTURE_2D,GL.GL_TEXTURE_WRAP_S, GL.GL_REPEAT );
		
	    // build celling
	    cellingTexture.bind();
	    gl.glBegin(GL.GL_QUAD_STRIP);
        gl.glTexCoord2f(0.0f, 0.0f);
		gl.glVertex3d(0, sizeY, 0);
		gl.glTexCoord2f(0.0f,4f);
		gl.glVertex3d(0, sizeY, sizeZ);
		gl.glTexCoord2f(8f, 0.0f);
		gl.glVertex3d(sizeX, sizeY, 0);
		gl.glTexCoord2f(8f,4f);
		gl.glVertex3d(sizeX, sizeY, sizeZ);
		gl.glEnd();

		// add light
		
		float[] colorGray   = {0.6f,0.6f,0.6f,1.0f};
		float[] colorRed    = {1.0f,0.0f,0.0f,1.0f};
		
		float posLight1[] = { (float)(-2*sizeX), (float)(-0.9*sizeY), (float)(8*sizeZ), 1f };
		float spotDirection[] = { 1f, 1f, -1f };
		gl.glLightfv( GL.GL_LIGHT1, GL.GL_POSITION, posLight1, 0 );
		gl.glLightf( GL.GL_LIGHT1, GL.GL_SPOT_CUTOFF, 29.0F );
		gl.glLightfv( GL.GL_LIGHT1, GL.GL_SPOT_DIRECTION, spotDirection, 0 );
  
		gl.glLightfv( GL.GL_LIGHT1, GL.GL_AMBIENT, colorGray, 0 );
		gl.glLightfv( GL.GL_LIGHT1, GL.GL_DIFFUSE, colorRed, 1 );
  
		gl.glLightf( GL.GL_LIGHT1, GL.GL_CONSTANT_ATTENUATION, 0.2f );		
		
	    gl.glEndList();
	    roomsWall.add(roomWall);
	    

		roomWall[4]=(new Point3D(sizeX+disp, 0, doors[2]));
		roomWall[5]=(new Point3D(sizeX+disp, 0, doors[3]));
		

		
		
	    
	    return room;
	}
 
	public void draw(GL gl) {
		
		
		
		gl.glCallList(room);
		
	}


	public Point3D[] getRoomWalls(int roomNumber) {
		return roomsWall.get(roomNumber);
	}


	public Point3D[] getFloorPoints() {
	
		return floorAbyss;
	}
}

